
import { AppDataSource } from '@/config/AppDataSource';
import { CreateFieldInfoDto, UpdateFieldInfoDto, QueryFieldInfoDto, DeleteFieldInfoDto, SelectOneFieldInfoDto, SortFieldInfoDto, CreateFieldInfoListDto } from '@/dto/fieldInfo.dto';
import { FieldInfo } from '@/entities/fieldInfo.entity';
import fieldInfoRepository from '@/repositories/fieldInfo.repository';


class FieldInfoService {

    /**
     * 创建
     * @param data  
     * @returns 
     */

    async add(data: CreateFieldInfoDto) {
        // 检查是否已存在
        const findOne = await fieldInfoRepository.fieldInfoExists(data.name);
        if (findOne) {
            if (findOne.name == data.name) {
                throw new Error('标题已存在！');
            }

        }
        // 创建
        return fieldInfoRepository.create(data);
    }
    async update(data: UpdateFieldInfoDto) {
        // 1. 检查是否存在
        const existingCategory = await fieldInfoRepository.findById(data.id);
        if (!existingCategory) {
            throw new Error("数据不存在")
        }


        const findOne = await fieldInfoRepository.findExcludeId(data);
        if (findOne) {
            if (findOne.name == data.name) {
                throw new Error('名称已存在！');
            }

        }
        // 更新
        return fieldInfoRepository.update(data);
    }

    async selectOne(reqData: SelectOneFieldInfoDto) {
        return fieldInfoRepository.findById(reqData.id)


    }

    async selectList(reqData: QueryFieldInfoDto) {
        return fieldInfoRepository.selectList(reqData)


    }
    async delete(reqData: DeleteFieldInfoDto) {
        let res = await fieldInfoRepository.delete(reqData);
        if (!res) {
            throw new Error("id不存在，无删除记录！")
        }
        return res


    }
    async sort(reqData: SortFieldInfoDto) {
        let res = await fieldInfoRepository.sort(reqData);
        return res


    }
    async addBatch(reqData: CreateFieldInfoListDto) {

        const submittedFields = reqData.fieldInfoList;
        const parentId = reqData.id
        const fieldRepo = AppDataSource.getRepository(FieldInfo);

        // 1. 获取数据库中现有的 parentId=1 的所有字段
        const existingFields = await fieldRepo.find({ where: { parentId } });

        // 2. 分类处理：找出需要新增、更新和删除的记录
        const submittedIds = new Set(submittedFields.map(f => f.id));
        const existingIds = new Set(existingFields.map(f => f.id));

        // 需要删除的字段（存在于数据库但不在提交数据中）
        const toDelete = existingFields.filter(f => !submittedIds.has(f.id));

        // 需要新增的字段（没有id或id不在现有数据中）
        const toCreate = submittedFields.filter(f => !f.id || !existingIds.has(f.id));

        // 需要更新的字段（id存在于现有数据中）
        const toUpdate = submittedFields.filter(f => f.id && existingIds.has(f.id));

        // 3. 执行数据库操作（使用事务保证原子性）
        await fieldRepo.manager.transaction(async transactionalEntityManager => {
            // 删除操作
            if (toDelete.length > 0) {
                await transactionalEntityManager.remove(FieldInfo, toDelete);
            }

            // 新增操作
            if (toCreate.length > 0) {
                // 设置parentId并移除可能的id（如果是部分提交的数据）
                const fieldsToSave = toCreate.map(f => {
                    const { id, ...rest } = f;
                    return { ...rest, parentId };
                });
                await transactionalEntityManager.save(FieldInfo, fieldsToSave);
            }

            // 更新操作
            if (toUpdate.length > 0) {
                // 只更新允许修改的字段，防止覆盖createdAt等字段
                const updatePromises = toUpdate.map(async field => {
                    const { id, createdAt, updatedAt, ...updateData } = field;
                    await transactionalEntityManager.update(
                        FieldInfo,
                        { id, parentId },
                        { ...updateData, updatedAt: () => 'CURRENT_TIMESTAMP' }
                    );
                });
                await Promise.all(updatePromises);
            }
        });
    }

    async selectByParentId(id:number){
        return await fieldInfoRepository.selectByParentId(id)

    }

}

export default new FieldInfoService();

